package com.nlx.notes.module.service.impl.flow;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.eventbus.Subscribe;
import com.nlx.notes.module.bean.bo.CategoryMonthStatisticsBo;
import com.nlx.notes.module.bean.dto.flow.FlowChangeDTO;
import com.nlx.notes.module.bean.dto.querydb.StatisticsQueryDTO;
import com.nlx.notes.module.bean.vo.statistics.CategoryMonthStatisticsVO;
import com.nlx.notes.module.core.consts.GlobalConst;
import com.nlx.notes.module.core.util.DateUtils;
import com.nlx.notes.module.entity.CategoryMonthStatistics;
import com.nlx.notes.module.entity.Transactions;
import com.nlx.notes.module.entity.Users;
import com.nlx.notes.module.service.ICategoryMonthStatisticsService;
import com.nlx.notes.module.service.ITransactionsService;
import com.nlx.notes.module.service.flow.FlowStatisticsManageService;
import com.nlx.notes.module.service.user.IUsersService;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class CategoryMonthStatisticsChangeServiceImpl implements FlowStatisticsManageService {

    final ICategoryMonthStatisticsService categoryMonthStatisticsService;

    final ITransactionsService transactionsService;

    final IUsersService usersService;

    private static final String STATISTICS_TYPE = "category_month_statistics";

    @Override
    public String getType() {
        return STATISTICS_TYPE;
    }


//    @PostConstruct
    public void  init(){
        List<Users> list = usersService.list();
        for (Users user : list) {
            List<Transactions> transactionsList = transactionsService.list(Wrappers.lambdaQuery(Transactions.class)
                    .eq(Transactions::getUserId,user.getId())
                    .eq(Transactions::getDelFlag, 0));
            if(CollUtil.isEmpty(transactionsList)){
                continue;
            }
            for (Transactions transactions : transactionsList) {
                FlowChangeDTO flowChangeDTO = new FlowChangeDTO();
                flowChangeDTO.setFlowNewDate(DateUtils.parseDate(transactions.getTransactionDate()));
                flowChangeDTO.setTransactionType(transactions.getTransactionType());
                flowChangeDTO.setUserId(transactions.getUserId());
                this.flowChange(flowChangeDTO);

            }

        }
    }



    @Subscribe
    @Override
    public void flowChange(FlowChangeDTO flowChangeDTO) {
        String month = DateUtils.formatMonth(flowChangeDTO.getFlowNewDate());
        String firstMonth = DateUtils.formatFirstDayFortMonth(flowChangeDTO.getFlowNewDate());
        String lastMonth = DateUtils.formatLastDayForMonth(flowChangeDTO.getFlowNewDate());
        log.info("当月：{}",month);
        List<CategoryMonthStatisticsBo> categoryMonthStatisticsBoList = transactionsService.findCategoryStatistics(firstMonth,lastMonth,
                flowChangeDTO.getUserId(),flowChangeDTO.getBookId());
        if (CollUtil.isEmpty(categoryMonthStatisticsBoList)) {
            // TODO 如果发现流水表中没有相关数据，说明都已经被删除，需要将分类统计表中的数据进行删除
            this.categoryMonthStatisticsService.removeCategory(month,flowChangeDTO.getBookId(),flowChangeDTO.getUserId());
            return;
        }
        StatisticsQueryDTO statisticsQueryDTO = new StatisticsQueryDTO();
        statisticsQueryDTO.setMonth(month);
        statisticsQueryDTO.setUserId(flowChangeDTO.getUserId());
        statisticsQueryDTO.setBookId(flowChangeDTO.getBookId());
//        categoryMonthStatisticsQueryDTO.setCategoryType(flowChangeDTO.getTransactionType());
        List<CategoryMonthStatisticsVO> categoryMonthStatisticsVOList = categoryMonthStatisticsService.findByMonth(statisticsQueryDTO);
        Map<Long,CategoryMonthStatisticsVO> longCategoryMonthStatisticsVOMap = null;
        if(CollUtil.isNotEmpty(categoryMonthStatisticsVOList)){
            longCategoryMonthStatisticsVOMap = categoryMonthStatisticsVOList.stream()
                    .collect(Collectors.toMap(
                            CategoryMonthStatisticsVO::getCategoryId,
                            Function.identity(),
                             (existing, replacement) -> replacement // 保留最后一个
                    ));
        }
        List<CategoryMonthStatistics> categoryMonthStatisticsList = new ArrayList<>();
        CategoryMonthStatistics categoryMonthStatistics;
        for (CategoryMonthStatisticsBo categoryMonthStatisticsBo : categoryMonthStatisticsBoList) {
            categoryMonthStatistics = new CategoryMonthStatistics();
            categoryMonthStatistics.setCategoryId(categoryMonthStatisticsBo.getCategoryId());
            categoryMonthStatistics.setMothDate(month);
            categoryMonthStatistics.setBookId(flowChangeDTO.getBookId());
            categoryMonthStatistics.setAmount(categoryMonthStatisticsBo.getAmount());
            categoryMonthStatistics.setUserId(flowChangeDTO.getUserId());
            categoryMonthStatistics.setRemarks(null);
            categoryMonthStatistics.setDelFlag(GlobalConst.DEL_FLAG_NORMAL);
            if(longCategoryMonthStatisticsVOMap != null && longCategoryMonthStatisticsVOMap.containsKey(categoryMonthStatistics.getCategoryId())){
                CategoryMonthStatisticsVO categoryMonthStatisticsVO = longCategoryMonthStatisticsVOMap.get(categoryMonthStatistics.getCategoryId());
                categoryMonthStatistics.setId(categoryMonthStatisticsVO.getId());
                longCategoryMonthStatisticsVOMap.remove(categoryMonthStatistics.getCategoryId());
            }else{
                categoryMonthStatistics.setCreatedTime(LocalDateTime.now());
            }
            categoryMonthStatistics.setCategoryId(categoryMonthStatisticsBo.getCategoryId());
            categoryMonthStatisticsList.add(categoryMonthStatistics);
        }
        if(CollUtil.isNotEmpty(categoryMonthStatisticsList)){
            categoryMonthStatisticsService.saveOrUpdateBatch(categoryMonthStatisticsList);
        }
        if(CollUtil.isNotEmpty(longCategoryMonthStatisticsVOMap)){
            Collection<CategoryMonthStatisticsVO> statisticsVOS = longCategoryMonthStatisticsVOMap.values();
            List<Long> statIds = new ArrayList<>();
            for (CategoryMonthStatisticsVO categoryMonthStatisticsVO : statisticsVOS){
                statIds.add(categoryMonthStatisticsVO.getId());
            }
            if(CollUtil.isNotEmpty(statIds)){
                categoryMonthStatisticsService.removeByIds(statIds);
            }
        }
    }

}
